﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RzCorportativo.DataAccess;

namespace RzCorportativo.Lib
{
    public class Consulta
    {
        private bool consultaHoraInicial { get; set; }
        private bool consultaHoraFinal { get; set; }

        public int ConsultaId { get; set; }
        public DateTime DateConsulta { get; set; }
        private bool atendidaChanged;
        private bool atendida;
        public bool Atendida { get { return this.atendida; } set { this.atendidaChanged = true; this.atendida = value; } }
        private TimeSpan horaInicial;
        public TimeSpan HoraEntrada
        {
            get { return this.horaInicial; }
            set
            {
                this.horaInicial = value;
                this.consultaHoraInicial = true;
            }
        }
        private TimeSpan horaFinal;
        public TimeSpan HoraSaida
        {
            get { return this.horaFinal; }
            set
            {
                this.horaFinal = value;
                this.consultaHoraFinal = true;
            }
        }
        public int PacienteId { get; set; }
        public int MedicoId { get; set; }
        public bool Avaliado { get; set; }
        public short EspecialidadeId { get; set; }
        public bool IsNew { get { return this.ConsultaId == 0; } }
        public string Sintomas { get; set; }
        public string Receita { get; set; }
        public Usuario Paciente { get; set; }
        public Medico Medico { get; set; }
        public Atestado Atestado { get; set; }
        public string Diagnostico { get; set; }

        RzCorportativo.DataAccess.Consultas model;

        public Consulta()
        {
            this.Paciente = new Usuario();
            this.Medico = new Medico();
        }

        public static Consulta CreateInstance(int consultaId)
        {
            Consulta e = new Consulta();
            RzCorportativo.DataAccess.RZCorporativoEntities db = new RzCorportativo.DataAccess.RZCorporativoEntities();
            var p = db.Consultas.Where(w => w.ConsultaId == consultaId).FirstOrDefault();
            if (p != null)
                e = e.CreateConsulta(p);
            return e;
        }

        public bool Salvar()
        {
            bool @result = false;
            Transaction.Begin((entity) =>
            {
                if (this.IsNew)
                    this.model = this.Insert(entity);
                else
                    this.model = this.Update(entity);
                this.ConsultaId = this.model.ConsultaId;
                if (this.Atestado != null)
                {
                    this.Atestado.Consulta = this;
                    if(!this.Atestado.Salvar())
                        throw new Exception("Falha ao salvar o atestado");
                }
                return true;
            }).OnError((ex) =>
            {
                @result = false;
            }).OnSuccess(() =>
            {
                @result = true;
            });
            return @result;
        }

        private RzCorportativo.DataAccess.Consultas Insert(RZCorporativoEntities entity)
        {
            var @item = this.CreateModel(entity);
            entity.AddToConsultas(@item);
            return @item;
        }

        private RzCorportativo.DataAccess.Consultas Update(RZCorporativoEntities entity)
        {
            var @item = this.CreateModel(entity);
            return @item;
        }

        private RzCorportativo.DataAccess.Consultas CreateModel(RZCorporativoEntities entity)
        {
            RzCorportativo.DataAccess.Consultas consulta = new RzCorportativo.DataAccess.Consultas();
            if (!this.IsNew)
            {
                consulta = entity.Consultas.Where(w => w.ConsultaId == this.ConsultaId).FirstOrDefault();
                if (consulta == null)
                    throw new Exception("Código inválido");
            }
            consulta.ConsultaId = this.ConsultaId;
            consulta.Data = this.DateConsulta;
            consulta.HoraEntrada = this.HoraEntrada;
            consulta.HoraSaida = this.HoraSaida;
            consulta.PacienteId = this.PacienteId;
            consulta.MedicoId = this.MedicoId;
            consulta.TipoConsultaId = this.EspecialidadeId;
            consulta.Realizado = this.Atendida;
            consulta.Avaliado = this.Avaliado;
            consulta.Sintomas = this.Sintomas;
            consulta.Receita = this.Receita;
            consulta.Diagnostico = this.Diagnostico;
            return consulta;
        }

        private Consulta CreateConsulta(RzCorportativo.DataAccess.Consultas item)
        {
            Consulta consulta = new Consulta();
            consulta.ConsultaId = item.ConsultaId;
            consulta.DateConsulta = item.Data;
            consulta.HoraEntrada = item.HoraEntrada;
            consulta.HoraSaida = item.HoraSaida;
            consulta.EspecialidadeId = item.TipoConsultaId;
            consulta.PacienteId = item.PacienteId;
            consulta.MedicoId = item.MedicoId;
            consulta.Atendida = item.Realizado;
            consulta.Medico = consulta.MedicoId == 0 ? new Medico() : Lib.Medico.CreateInstace(consulta.MedicoId);
            consulta.Paciente = consulta.PacienteId == 0 ? new Usuario() : Lib.Usuario.CreateInstace(consulta.PacienteId);
            consulta.Avaliado = item.Avaliado;
            consulta.Sintomas = item.Sintomas;
            consulta.Receita = item.Receita;
            consulta.Diagnostico = item.Diagnostico;
            consulta.Atestado = new Atestado();
            if (item.Atestado != null && item.Atestado.FirstOrDefault() != null)
            {
                consulta.Atestado.CreateAtestado(item.Atestado.FirstOrDefault());
            }
            return consulta;
        }

        public static List<Consulta> Listar(Consulta consulta)
        {
            if (consulta == null)
                consulta = new Consulta();
            List<Consulta> lista = new List<Consulta>();
            RzCorportativo.DataAccess.RZCorporativoEntities db = new RZCorporativoEntities();
            lista = db.Consultas.Where(w =>
                    ((consulta.ConsultaId == 0) || (consulta.ConsultaId == w.ConsultaId)) &&
                    ((!consulta.atendidaChanged) || (consulta.atendida == w.Realizado)) &&
                    ((consulta.DateConsulta == DateTime.MinValue) || (consulta.DateConsulta == w.Data)) &&
                    ((!consulta.consultaHoraInicial && !consulta.consultaHoraFinal) || (consulta.HoraEntrada >= w.HoraEntrada && consulta.HoraSaida <= w.HoraSaida)) &&
                    ((consulta.EspecialidadeId == 0) || (consulta.EspecialidadeId == w.TipoConsultaId)) &&
                    ((consulta.PacienteId == 0) || (consulta.PacienteId == w.PacienteId)) &&
                    ((consulta.MedicoId == 0) || (consulta.MedicoId == w.MedicoId))
                ).ToList().Select(s => consulta.CreateConsulta(s)).ToList();
            return lista;
        }

        public static List<Consulta> VerificarAprovacao(Consulta consulta)
        {
            if (consulta == null)
                consulta = new Consulta();
            List<Consulta> lista = new List<Consulta>();
            RzCorportativo.DataAccess.RZCorporativoEntities db = new RZCorporativoEntities();
            lista = db.Consultas.Where(w =>
                    ((consulta.ConsultaId == 0) || (consulta.ConsultaId == w.ConsultaId)) &&
                    ((!consulta.atendidaChanged) || (consulta.atendida == w.Realizado)) &&
                    ((consulta.DateConsulta == DateTime.MinValue) || (consulta.DateConsulta == w.Data)) &&
                    ((!consulta.consultaHoraInicial && !consulta.consultaHoraFinal) ||
                    ((consulta.HoraEntrada >= w.HoraEntrada && consulta.HoraEntrada <= w.HoraSaida) ||
                    (consulta.HoraSaida >= w.HoraEntrada && consulta.HoraSaida <= w.HoraSaida))) &&
                    ((consulta.EspecialidadeId == 0) || (consulta.EspecialidadeId == w.TipoConsultaId)) &&
                    ((consulta.PacienteId == 0) || (consulta.PacienteId == w.PacienteId)) &&
                    ((consulta.MedicoId == 0) || (consulta.MedicoId == w.MedicoId))
                ).ToList().Select(s => consulta.CreateConsulta(s)).ToList();
            return lista;
        }

    }

}
